import React, {useState, useEffect, useRef, useCallback} from 'react';
import style from './Comments.module.scss';
import {Button, Divider, Input, List, message, Popconfirm, Radio, Result, Space, Statistic, Typography} from 'antd';
import {getBook, getComments, getWordCloud, postSearchKey} from '../../network/requests';
import {CommentsModel} from './CommentsModel';
import {Line, Mix, Pie, WordCloud} from '@ant-design/charts';
import {useSearchParams} from 'react-router-dom';
import {BookDetail} from '../../components/BookDetail';
import {usePrefersColorScheme} from '@anatoliygatt/use-prefers-color-scheme';

const {Search} = Input;

const plotMap={};

export function Comments() {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);
  const [lineData, setLineData] = useState(null);
  const [avgData, setAvgData] = useState(null);
  const [wordCloud, setWordCloud] = useState(null);
  const [overallData, setOverallData] = useState(null);
  const [dayValues, setDayValues] = useState([]);
  const [lineSeries, setLineSeries] = useState(null);
  const [book, setBook] = useState(null);
  const [searchContent, setSearchContent] = useState('');
  const model = useRef(null);
  const [searchParams, setSearchParams] = useSearchParams({});
  const [noBook, setNoBook]=useState(false);
  const [noComments, setNoComments]=useState(false);
  const prefersColorScheme = usePrefersColorScheme();
  const isDarkMode = prefersColorScheme === 'dark';

  useEffect(() => {
    const q = searchParams.get('query');
    if (q) {
      handleSearch(q);
      setSearchContent(q);
    }
  }, []);

  useEffect(()=>{
    if (!data) {
      return;
    }
    const commentsModel=new CommentsModel(data);
    setLineSeries('month');
    console.log(commentsModel);
    setAvgData(commentsModel.monthAvg);
    setOverallData(commentsModel.overall);
    setDayValues(commentsModel.dayArray.map((({key})=>key)));
    model.current=commentsModel;
  }, [data]);

  useEffect(()=>{
    if (!model.current) {
      return;
    }
    if (lineSeries==='week') {
      setLineData(model.current.weekArray);
    } else if (lineSeries==='month') {
      setLineData(model.current.monthArray.concat(model.current.monthPredict));
    } else {
      setLineData(model.current.dayArray);
    }
  }, [lineSeries]);

  const handleSearch=useCallback((isbn)=>{
    setSearchParams({query: isbn});
    setLoading(true);
    const commentPromise=getComments(isbn).then((data)=>{
      if (!data.length) {
        setNoComments(true);
        return;
      } else {
        setNoComments(false);
      }
      setData(data);
    });
    const bookPromise=getBook(isbn).then((data)=>{
      setBook(data);
      setNoBook(false);
    }).catch(()=>{
      setNoBook(true);
    });
    getWordCloud(isbn).then((data)=>{
      if (data) {
        setWordCloud(JSON.parse(data.content));
      }
    });
    Promise.all([commentPromise, bookPromise]).catch(()=>{
      message.error('网络错误');
    }).finally(()=>{
      setLoading(false);
    });
  }, []);

  const commonConfig={
    padding: 'auto',
    appendPadding: [32, 24, 16, 24],
    theme: isDarkMode?'dark':'default', // 'dark',
  };

  const lineConfig = {
    ...commonConfig,
    meta: {
      key: {alias: '时间'},
      value: {alias: '数量'},
    },
    data: lineData,
    xField: 'key',
    yField: 'value',
    smooth: true,
    seriesField: 'type',
    legend: {
      position: 'top',
      offsetY: 8,
    },
    xAxis: {
      title: {
        text: '时间',
      },
      label: {
        offset: 16,
      },
    },
    yAxis: {
      title: {
        text: '数量',
      },
      label: {
        offset: 16,
      },
    },
    onReady(plot) {
      plotMap.line=plot;
      plot.on('plot:mousemove', (e)=>{
        const {x, y} = e.gEvent;
        const currentData = plot.chart.getTooltipItems({x, y})[0]?.title;
        const chartData = plotMap.mix.chart.views[1].getData();
        for (let i = 0; i < chartData?.length; i++) {
          if (chartData[i].key === currentData) {
            const {x, y} = plotMap.mix.chart.views[1].getXY(chartData[i]);
            plotMap.mix.chart.views[1].showTooltip({x, y});
            break;
          }
        }
      });
      plot.on('plot:mouseleave', ()=>{
        plotMap.mix.chart.views[1].showTooltip(false);
      });
    },
  };

  const scatterConfig = data && {
    ...commonConfig,
    data: data.map(({time, content, score})=>({
      time: time.slice(0, 10),
      content, score,
    })),
    xField: 'time',
    yField: 'score',
    pointStyle: {
      // stroke: '#777777',
      lineWidth: 0,
      fill: 'rgb(91,143,249)',
      opacity: 0.05,
    },
    meta: {
      time: {
        values: dayValues,
        alias: '时间',
      },
      score: {alias: '评分'},
      content: {alias: '内容'},
    },
    size: 12,
    // tooltip: {
    //   fields: ['time', 'score', 'content'],
    //   shared: true,
    // },
    xAxis: {
      title: {
        text: '时间',
      },
      label: {
        offset: 18,
      },
    },
    yAxis: {
      title: {
        text: '评价',
      },
      label: {
        offset: 16,
      },
      min: 1,
      max: 5,
    },
  };

  const scoreConfig = {
    data: avgData,
    ...commonConfig,
    xField: 'key',
    yField: 'avg',
    // tooltip: {
    //   fields: ['key', 'avg'],
    //   shared: true,
    // },
    meta: {
      key: {alias: '时间'},
      avg: {alias: '平均评分'},
    },
    smooth: true,
    legend: {
      position: 'top',
      offsetY: 8,
    },
    xAxis: false,
    yAxis: {
      label: {
        offset: 16,
      },
      min: 1,
      max: 5,
    },
    lineStyle: {
      stroke: 'rgba(90,216,166,0.93)',
    },
  };

  const pieConfig = overallData&&{
    ...commonConfig,
    width: 400,
    height: 250,
    legend: false,
    data: [{
      type: '好评',
      value: overallData.goodCount,
    }, {
      type: '中评',
      value: overallData.mediumCount,
    }, {
      type: '差评',
      value: overallData.badCount,
    }],
    angleField: 'value',
    colorField: 'type',
    radius: 0.75,
    color: ['rgba(90,216,166,0.93)', 'rgba(225,186,86,0.89)', 'rgba(243,87,87,0.81)'],
    label: {
      type: 'spider',
      labelHeight: 28,
      content: '{name}\n{percentage}',
    },
    // 添加 中心统计文本 交互
    interactions: [
      {
        type: 'element-selected',
      },
      {
        type: 'element-active',
      },
    ],
  };

  const wordCloudConfig = {
    height: 250,
    width: 350,
    ...commonConfig,
    data: wordCloud,
    wordField: 'x',
    weightField: 'count',
    wordStyle: {
      fontFamily: 'Verdana',
      fontSize: [24, 80],
      fontWeight: 'bold',
    },
    // 设置交互类型
    interactions: [
      {
        type: 'element-active',
      },
    ],
    state: {
      active: {
        // 这里可以设置 active 时的样式
        style: {
          lineWidth: 1,
        },
      },
    },
  };
  return <>
    <Search loading={loading} value={searchContent} onChange={(e)=>setSearchContent(e.target.value)} placeholder={'请输入 ISBN'} onSearch={handleSearch} size={'large'} enterButton="分析"/>
    {/* <Divider/>*/}
    {
      book&&<List itemLayout={'vertical'}><BookDetail small={true} book={book}/></List>
    }
    <Divider/>
    {
      data&&overallData&&
      <Space size={'middle'} className={style.section} direction={'vertical'}>
        <Typography.Title level={4}>总览</Typography.Title>
        <div className={style.overall}>
          <Pie className={style.graph} {...pieConfig}/>
          <Statistic title={'总评论数'} value={data.length}/>
          <Statistic title={'平均评分'} value={overallData.avgScore.toFixed(2)}/>
          {wordCloud&&<WordCloud className={style.graph} {...wordCloudConfig}/>}
        </div>
      </Space>
    }
    {lineData&&
      <Space size={'middle'} className={style.section} direction={'vertical'}>
        <Typography.Title level={4}>评论数</Typography.Title>
        <Radio.Group value={lineSeries} onChange={(e)=>setLineSeries(e.target.value)}>
          <Radio.Button value={'day'}>日视图</Radio.Button>
          <Radio.Button value={'week'}>周视图</Radio.Button>
          <Radio.Button value={'month'}>月视图</Radio.Button>
        </Radio.Group>
        <Line className={style.graph} {...lineConfig}/>
      </Space>
    }
    {data&&avgData&&
      <Space size={'middle'} className={style.section} direction={'vertical'}>
        <Typography.Title level={4}>评价趋势</Typography.Title>
        <Mix
          className={style.graph} appendPadding={true}
          syncViewPadding={true}
          plots={[
            {type: 'scatter', options: scatterConfig},
            {type: 'line', options: scoreConfig},
          ]}
          tooltip={{
            customItems: (originalItems) => {
              if (originalItems[0]?.data?.content) {
                return [...originalItems, {
                  name: '内容',
                  value: originalItems[0]?.data?.content,
                  marker: true,
                  color: '#5B8FF9',
                }];
              } else {
                return [
                  {
                    ...originalItems[0],
                    color: '#55ca9b',
                  },
                ];
              }
            },
          }}
          theme={isDarkMode?'dark':'default'}
          onReady={(plot)=>{
            plotMap.mix=plot;
            plot.on('plot:mousemove', (e)=>{
              const {x, y} = e.gEvent;
              const currentData = plot.chart.views[1].getTooltipItems({x, y})[0]?.title;
              const chartData = plotMap.line.chart.getData();
              for (let i = 0; i < chartData?.length; i++) {
                if (chartData[i].key === currentData) {
                  const {x, y} = plotMap.line.chart.getXY(chartData[i]);
                  plotMap.line.chart.showTooltip({x, y});
                  break;
                }
              }
            });
            plot.on('plot:mouseleave', ()=>{
              plotMap.line.chart.showTooltip(false);
            });
          }}
        />
      </Space>
    }
    {
      noBook&&
      <Result status="404"
        title="还未建立该书籍的索引"
        subTitle={'ISBN ' + searchContent + ' 还没有建立索引'}
      />
    }
    {
      !noBook&&noComments&&
      <Result status="404"
        title="还未爬取评论"
        subTitle={'书籍 ' + searchContent + ' 还没有爬取评论，可以立即爬取'}
        extra={
          <Popconfirm onConfirm={()=>{
            postSearchKey({
              maxCount: 0,
              platform: ['comment'],
              key: searchContent,
            }).then(()=>{
              message.success('创建成功');
            }).catch(()=>{
              message.error('创建失败');
            });
          }} title={'爬取这本书的评论？'}>
            <Button type="primary">开始爬取</Button>
          </Popconfirm>
        }
      />
    }
  </>;
}
